#ifndef	__MULTICASTSENDERHELPER_HPP__
#define __MULTICASTSENDERHELPER_HPP__

#include <iostream>
#include <sstream>
#include <string>
#include <boost/asio.hpp>
#include "boost/bind.hpp"
#include "boost/date_time/posix_time/posix_time_types.hpp"

const int maxMessageCount = 10;

	namespace network
	{
		namespace helper
		{

	class MulticastSenderHelper
	{
	public:

		MulticastSenderHelper( const boost::asio::ip::address& multicast_address);
		virtual ~MulticastSenderHelper();

		template < class T >
		void multicast( network::buffer::BasicBuffer _packet, void (T::*function) (const boost::system::error_code& error, size_t), T* _class, float _timeOut = -1.0f  )
		{
			//m_packet = &_packet;
			m_socket.async_send_to( _packet, m_endpoint,
				boost::bind( &MulticastSenderHelper::handle_send_to<T>,this, function, _class,
				boost::asio::placeholders::error)
				);
			
			if( _timeOut >= 0 )
			{
				m_timer.expires_from_now(boost::posix_time::seconds(_timeOut));
				m_timer.async_wait( boost::bind(&MulticastSenderHelper::handle_timeout, this) );
			}
			//m_ioService.run();
		}

		virtual void handle_receive_from(const boost::system::error_code& error, size_t bytes_recvd);
		template < class T >
		void handle_send_to( void (T::*function) ( const boost::system::error_code&, std::size_t ), T* _class,
												const boost::system::error_code& error)
		{
			if ( !error )
			{
				try
				{
					m_socket.async_receive_from(
							boost::asio::buffer( *m_data, max_length), m_serverEndpoint,
							boost::bind( function, _class,
							  boost::asio::placeholders::error,
							  boost::asio::placeholders::bytes_transferred));

				}catch( boost::system::system_error& e )
				{	
					
#if defined(_DEBUG) && defined(_OUTPUT)
					std::cout << "error boost : " << e.what() << std::endl;
#endif
				}
			}
#if defined(_DEBUG) && defined(_OUTPUT)
			else
				std::cout << " [ MulticastSenderHelper ] Error while sending party request..." << std::endl;
#endif

		}

		void handle_timeout();

		void close();
		
		void handle_stop();

		protected:
			boost::asio::io_service				m_ioService;
			boost::asio::ip::udp::endpoint		m_endpoint;
			boost::asio::ip::udp::socket		m_socket;
			boost::asio::deadline_timer			m_timer;
			int									m_messageCount;
			//network::buffer::BasicBuffer*		m_packet;

			// response part
			enum { max_length = 1024 };
			boost::shared_ptr<std::vector< unsigned char > >	m_data;
			boost::asio::ip::udp::endpoint						m_serverEndpoint;
	};

	}	//	namespace helper
}	//	//	namespace network

#endif	// __MULTICASTSENDERHELPER_HPP__